package hu.bme.mit.androtext.androgen.serializer;

import com.google.inject.Inject;
import com.google.inject.Provider;
import hu.bme.mit.androtext.androgen.androGenDsl.AndroGenDslPackage;
import hu.bme.mit.androtext.androgen.androGenDsl.AndroidGeneratorModel;
import hu.bme.mit.androtext.androgen.androGenDsl.TargetApplication;
import hu.bme.mit.androtext.androgen.services.AndroGenDslGrammarAccess;
import hu.bme.mit.androtext.common.commons.CommonsPackage;
import hu.bme.mit.androtext.common.commons.Import;
import hu.bme.mit.androtext.common.serializer.CommonsSemanticSequencer;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;

@SuppressWarnings("restriction")
public class AbstractAndroGenDslSemanticSequencer extends AbstractSemanticSequencer {

	@Inject
	protected AndroGenDslGrammarAccess grammarAccess;
	
	@Inject
	protected ISemanticSequencerDiagnosticProvider diagnosticProvider;
	
	@Inject
	protected ITransientValueService transientValues;
	
	@Inject
	@GenericSequencer
	protected Provider<ISemanticSequencer> genericSequencerProvider;
	
	protected ISemanticSequencer genericSequencer;
	
	@Inject
	protected Provider<CommonsSemanticSequencer> superSequencerProvider;
	 
	protected CommonsSemanticSequencer superSequencer; 
	
	@Override
	public void init(ISemanticSequencer sequencer, ISemanticSequenceAcceptor sequenceAcceptor, Acceptor errorAcceptor) {
		super.init(sequencer, sequenceAcceptor, errorAcceptor);
		this.genericSequencer = genericSequencerProvider.get();
		this.genericSequencer.init(sequencer, sequenceAcceptor, errorAcceptor);
		this.superSequencer = superSequencerProvider.get();
		this.superSequencer.init(sequencer, sequenceAcceptor, errorAcceptor); 
	}
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == AndroGenDslPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case AndroGenDslPackage.ANDROID_GENERATOR_MODEL:
				if(context == grammarAccess.getAndroidGeneratorModelRule()) {
					sequence_AndroidGeneratorModel(context, (AndroidGeneratorModel) semanticObject); 
					return; 
				}
				else break;
			case AndroGenDslPackage.TARGET_APPLICATION:
				if(context == grammarAccess.getTargetApplicationRule()) {
					sequence_TargetApplication(context, (TargetApplication) semanticObject); 
					return; 
				}
				else break;
			}
		else if(semanticObject.eClass().getEPackage() == CommonsPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case CommonsPackage.IMPORT:
				if(context == grammarAccess.getImportRule()) {
					sequence_Import(context, (Import) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     targetApplications+=TargetApplication*
	 */
	protected void sequence_AndroidGeneratorModel(EObject context, AndroidGeneratorModel semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     importedNamespace=QualifiedNameWithWildCard
	 */
	protected void sequence_Import(EObject context, Import semanticObject) {
		superSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (application=[AndroidApplication|ID] projectName=QualifiedName packageName=QualifiedName? target=ApiLevel)
	 */
	protected void sequence_TargetApplication(EObject context, TargetApplication semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
}
